home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_2
/
wiconify
/
wiconsetter.lzh
/
wIdentify
/
wIdentify.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-19
|
13KB
|
529 lines
/*
* WIDENTIFY A companion utility to wIconSetter and wIconify that allows
* you to determine the commands necessary to properly identify
* a window or screen in the wIconSetter initialization file.
*
* wIdentify.c main code for wIdentify.
*
* Copyright 1990 by Davide P. Cervone, all rights reserved.
* You may use this code, provided this copyright notice is kept intact.
*/
#include "wIdentify.h"
#include <devices/input.h>
static char *program = PROGRAM;
static char *copyright = COPYRIGHT;
struct MsgPort *IdPort; /* Port for messages in when NEW is specified */
static char *WindowName; /* Name of window to identify */
static char *ScreenName; /* Name of screen holding window */
/* Storage for SetFunction return values */
long OldOpenWindow;
long OldSetWindowTitles;
long OldOpenScreen;
#define TOUPPER(c) (((c)>='a'&&(c)<='z')?(c)-'a'+'A':c)
#define MATCH(n1,n2) (PrefixMatch(n1,n2) == 0)
#define ARGMATCH(s) (stricmp(argv[0],s) == 0)
#define FUNCTION(s) (ARGMATCH(s) && function == JUST_EXIT)
#define NAME(s)\
(ARGMATCH(s) && (function == JUST_EXIT || function == IDENTIFY_ONE))
#define PARAMETER(f,a,s)\
{\
if (argc >= 2)\
{\
if (function == JUST_EXIT) function = f;\
a = argv[1];\
argc--; argv++;\
} else {\
printf(s);\
function = SHOW_USAGE;\
}\
}
/*
* DoExit()
*
* General purpose error-exit routine. Print an error message if one was
* supplied (it can have up to three parameters), and then clean up any
* memory, libraries, etc. that need to be handled before exiting.
*/
void DoExit(s,x1,x2,x3)
char *s, *x1, *x2, *x3;
{
long status = EXIT_OK;
if (s != NULL)
{
printf(s,x1,x2,x3);
printf("\n");
status = EXIT_ERROR;
}
if (IdPort) DeletePort(IdPort);
if (IntuitionBase) CloseLibrary(IntuitionBase);
exit(status);
}
/*
* CheckLibOpen()
*
* Call OpenLibrary() for the specified library, and check that the
* open succeeded.
*/
static void CheckLibOpen(lib,name,rev)
APTR *lib;
char *name;
int rev;
{
extern APTR OpenLibrary();
if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
DoExit("Can't open %s",name);
}
/*
* SetVectors()
*
* Set the Intuition library vectors for the routines we are trapping
* to the routines specified by the handler. Save the old routine pointers
* for later replacement.
*/
static void SetVectors()
{
OldOpenWindow = SetFunction(IntuitionBase,&LVOOpenWindow,&aOpenWindow);
OldSetWindowTitles =
SetFunction(IntuitionBase,&LVOSetWindowTitles,&aSetWindowTitles);
OldOpenScreen = SetFunction(IntuitionBase,&LVOOpenScreen,&aOpenScreen);
}
/*
* UnSetVectors()
*
* Replace the old Intuition library vectors, but make sure that no one
* else has changed them behind our back. If they are not the same as
* what we set them to originally, then put back the ones that we found,
* and return an error status.
*/
static int UnSetVectors()
{
long NewOpenWindow;
long NewSetWindowTitles;
long NewOpenScreen;
int status = FALSE;
NewOpenWindow = SetFunction(IntuitionBase,&LVOOpenWindow,OldOpenWindow);
NewSetWindowTitles =
SetFunction(IntuitionBase,&LVOSetWindowTitles,OldSetWindowTitles);
NewOpenScreen = SetFunction(IntuitionBase,&LVOOpenScreen,OldOpenScreen);
if (NewOpenWindow != (long) &aOpenWindow ||
NewSetWindowTitles != (long) &aSetWindowTitles ||
NewOpenScreen != (long) &aOpenScreen)
{
SetFunction(IntuitionBase,&LVOOpenWindow,NewOpenWindow);
SetFunction(IntuitionBase,&LVOSetWindowTitles,NewSetWindowTitles);
SetFunction(IntuitionBase,&LVOOpenScreen,NewOpenScreen);
status = TRUE;
}
return(status);
}
/*
* ParseArguments()
*
* Initialize the wIdentify function to just exiting.
* If we were started from the WB, just exit.
* If we did not have any parameters, identify active window.
* While there are more arguments to consider,
* Get the next argument
* If it is NEW or ALL, set the function appropriately.
* If it is WINDOW, get the window name or show an error.
* If it is SCREEN, get the screen name or show an error.
* Otherwise show un-recognized parameter error and show usage.
* Return the function to perform.
*/
static int ParseArguments(argc,argv)
int argc;
char **argv;
{
int function = JUST_EXIT;
if (argc == 0) return(JUST_EXIT);
if (argc == 1) return(IDENTIFY_ONE);
while (--argc > 0)
{
argv++;
if (FUNCTION("NEW")) function = IDENTIFY_NEW;
else if (FUNCTION("ALL")) function = IDENTIFY_ALL;
else if (NAME("WINDOW"))
PARAMETER(IDENTIFY_ONE,WindowName,"Window name required\n")
else if (NAME("SCREEN"))
PARAMETER(IDENTIFY_ONE,ScreenName,"Screen name required\n")
else
{
printf("Unrecognized parameter '%s'\n",*argv);
function = SHOW_USAGE;
}
}
return(function);
}
/*
* PrefixMatch()
*
* Case-insensitive prefix match. NULL pointers and empty strings
* only match themselves, and are not considered prefixes to any string.
*
* Return <0 if the first is smaller than the second,
* =0 if the first is a prefix of the second,
* >1 if the first is larger than the second.
*/
static int PrefixMatch(s1,s2)
char *s1,*s2;
{
int match = -1;
if (s1)
{
if (s2)
{
while (TOUPPER(*s1) == TOUPPER(*s2) && *s2 != 0) s1++,s2++;
if (*s1 == 0) match = 0; else match = *s1 - *s2;
} else match = 1;
} else if (s2 == NULL) match = 0;
return(match);
}
/*
* *FindScreen()
*
* Lock IntuitionBase so nothing happens while we look.
* If there is a name to look for,
* Start at the first screen, and look for a screen whose title
* matches the given name. If none, return NULL.
* Otherwise, use the active screen.
* Unlock Intuition.
* Return the screen pointer found, if any.
*/
static struct Screen *FindScreen(ScreenName)
char *ScreenName;
{
struct Screen *theScreen;
long ILock, LockIBase();
ILock = LockIBase(0L);
if (ScreenName)
{
theScreen = IntuitionBase->FirstScreen;
while (theScreen && PrefixMatch(ScreenName,theScreen->Title))
theScreen = theScreen->NextScreen;
} else {
theScreen = IntuitionBase->ActiveScreen;
}
UnlockIBase(ILock);
return(theScreen);
}
/*
* *FindWindow()
*
* Lock Intuition so nothing happens while we look.
* If there is a window name given,
* Start with the first window on the screen and look through
* the window list for one that matches the given name.
* Return NULL if none found.
* Otherwise, use the active window.
* Unlock Intuition.
* Return the window pointer, if any.
*/
static struct Window *FindWindow(WindowName,theScreen)
char *WindowName;
struct Screen *theScreen;
{
struct Window *theWindow;
long ILock, LockIBase();
ILock = LockIBase(0L);
if (WindowName)
{
theWindow = theScreen->FirstWindow;
while (theWindow && PrefixMatch(WindowName,theWindow->Title))
theWindow = theWindow->NextWindow;
} else {
theWindow = IntuitionBase->ActiveWindow;
}
UnlockIBase(ILock);
return(theWindow);
}
/*
* DoMessage()
*
* Get the message's screen and window pointers.
* If the Message has a program, print its name, otherwise print '[Unknown]'
* If the screen has a title, print it, otherwise print '[NULL]'
* If this is not a screen-open message
* if the window has a title, print it, otherwise print '[NULL]'
*/
static void DoMessage(theMessage)
struct IdMessage *theMessage;
{
struct Window *theWindow = theMessage->Window;
struct Screen *theScreen = theMessage->Screen;
if (theMessage->Program)
printf("\nProgram: '%s'\n",theMessage->Program);
else
printf("\nProgram: [Unknown]\n");
if (theScreen->DefaultTitle)
printf(" Screen: '%s'\n",theScreen->DefaultTitle);
else
printf(" Screen: [NULL]\n");
if (theWindow != SCREENICON)
{
if (theWindow->Title)
printf(" Window: '%s'\n",theWindow->Title);
else
printf(" Window: [NULL]\n");
}
}
/*
* IdentifyWindow()
*
* Get ther port of the window
* If there is a port, and it has a task to signal,
* Get the task's name and print it, otherwise print '[ANY]'
* If the window's screen has a title, print it, otherwise print '[NULL]'
* If the window itself has a title, print it, otherwise print '[NULL]'
*/
static void IdentifyWindow(theWindow)
struct Window *theWindow;
{
struct MsgPort *thePort;
char Program[MAXNAME];
thePort = theWindow->UserPort;
if (thePort && thePort->mp_SigTask != NULL &&
(thePort->mp_Flags & PF_ACTION) == PA_SIGNAL)
GetProgramName(Program,thePort->mp_SigTask),
printf("Program: '%s'\n",Program);
else
printf("Program: [ANY]\n");
if (theWindow->WScreen->DefaultTitle)
printf(" Screen: '%s'\n",theWindow->WScreen->DefaultTitle);
else
printf(" Screen: [NULL]\n");
if (theWindow->Title)
printf(" Window: '%s'\n",theWindow->Title);
else
printf(" Window: [NULL]\n");
}
/*
* IdentifyScreen()
*
* Get the screen's first window
* While there are still windows to consider
* Print a blank line then the window's name, etc.
* Go on to the next window
*/
static void IdentifyScreen(theScreen)
struct Screen *theScreen;
{
struct Window *theWindow;
Forbid();
theWindow = theScreen->FirstWindow;
while (theWindow)
{
printf("\n");
IdentifyWindow(theWindow);
theWindow = theWindow->NextWindow;
}
Permit();
}
/*
* IdentifyNew()
*
* Create a port for messages from the handler
* Trap the intuition routines, and give a message that we are running
* Get the wait signals
* As long as we haven't bee told otherwise,
* Wait for a message or CTRL-C
* While ther are messages in the port,
* Do each message and reply to it
* If we were signalled to stop,
* Try to remove the trap routines
* If unsuccessful, print a message, otherwise, end the loop
* Indicate that wIdentify is finished.
*/
static void IdentifyNew()
{
ULONG Signals;
ULONG WaitSignals;
int NotDone = TRUE;
struct IdMessage *theMessage;
IdPort = CreatePort(0,0);
if (IdPort == NULL) DoExit("Can't Create IdPort");
SetVectors();
printf("wIdentify Running...\n");
WaitSignals = (ONE << IdPort->mp_SigBit) | SIGBREAKF_CTRL_C;
while (NotDone)
{
Signals = Wait(WaitSignals);
while (theMessage = GetMsg(IdPort))
{
DoMessage(theMessage);
ReplyMsg(theMessage);
}
if (Signals & SIGBREAKF_CTRL_C)
{
NotDone = UnSetVectors();
if (NotDone)
{
printf("[vectors have been changed - can't cancel]\n");
printf("wIdentify Running...\n");
}
}
}
printf("\nwIdentify Done\n");
}
/*
* IdentifyOne()
*
* Find the specified screen.
* If can't find it, error
* Otherwise,
* If a window was not specified, but a screen was, do the entire screen,
* Otherwise
* Find the specified window on the screen
* If found, identify it, otherwise error
*/
static void IdentifyOne()
{
struct Window *theWindow;
struct Screen *theScreen;
Forbid();
theScreen = FindScreen(ScreenName);
if (theScreen == NULL)
{
printf("Can't find screen '%s'\n",ScreenName);
} else {
if (WindowName == NULL && ScreenName)
{
IdentifyScreen(theScreen);
printf("\n");
} else {
theWindow = FindWindow(WindowName,theScreen);
if (theWindow) IdentifyWindow(theWindow);
else printf("Can't find window '%s' on screen '%s'\n",
WindowName,theScreen->DefaultTitle);
}
}
Permit();
}
/*
* IdentifyAll()
*
* Get the first Intuition screen
* While there are more screens
* Identify all windows on the screen and go to the next screen
*/
static void IdentifyAll()
{
struct Screen *theScreen;
Forbid();
theScreen = IntuitionBase->FirstScreen;
while (theScreen)
{
IdentifyScreen(theScreen);
theScreen = theScreen->NextScreen;
}
Permit();
printf("\n");
}
/*
* main()
*
* Open the Intuition library
* Parse the argument list, and do the proper thing:
* Show usage, identify new windows, one window, or all windows
* Exit and clean up
*/
void main(argc,argv)
int argc;
char **argv;
{
CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
switch(ParseArguments(argc,argv))
{
case SHOW_USAGE:
printf("Usage: %s\n",USAGE);
break;
case IDENTIFY_NEW:
IdentifyNew();
break;
case IDENTIFY_ONE:
IdentifyOne();
break;
case IDENTIFY_ALL:
IdentifyAll();
break;
}
DoExit(NULL);
}